home *** CD-ROM | disk | FTP | other *** search
- /*
- Patch.h
-
- Macros for patching traps and vectors.
-
- by Mouse Herrell & Patrick Beard.
-
- © 1991 Berkeley Systems Inc.
- */
-
- #pragma once
-
- #ifndef __PATCH__
- #define __PATCH__
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
- #ifndef __OSUTILS__
- #include <OSUtils.h>
- #endif
- #ifndef __STDDEF__
- #include <stddef.h>
- #endif
-
- // Macros & Inline glue to make patching easier.
-
- #define GetTrapType(x) (((x) & 0x800) != 0)
- #define InterruptMask(x) ((x) << 8)
- #define cSupervisorState 0x2000
-
- #pragma parameter __D0 GetA4
- void* GetA4(void) = { 0x200c };
-
- #pragma parameter __D0 SetA4(__D0)
- void* SetA4(void* newA4) = { 0xc18c };
-
- #pragma parameter __D0 GetA5
- void* GetA5(void) = { 0x200d };
-
- #pragma parameter __D0 GetA0
- void* GetA0(void) = { 0x2008 };
-
- #pragma parameter __D0 GetSR
- short GetSR(void) = { 0x40c0 };
-
- #pragma parameter __D0 SetSR(__D1)
- short SetSR(short) = { 0x40c0, 0x46c1 };
-
- // tests and sets indivisibly (to avoid race conditions) using BSET.B #0
- #pragma parameter __D0 SetFlag(__A0)
- Boolean SetFlag(Boolean*) = { 0x08d0, 0x0000, 0x56c0 };
-
- // types & constants.
-
- enum PatchError {
- eAbstractErr = 128, // An abstract method was called.
- eBuriedPatchErr, // The patch removal failed because the vector has changed.
- eEndPatchErrors
- };
-
- typedef enum PatchError PatchError;
-
- enum {
- ePatchOff = 0,
- ePatchOn
- };
-
- typedef char PatchState;
-
- // universal pointer to function.
-
- typedef void* PatchProcPtr;
- typedef PatchProcPtr *PatchVectorPtr; // pointer to a PatchProcPtr.
-
- // stub of code that is allocated for every patch.
-
- class Patch;
-
- struct PatchStub {
- short itsJsrJmp;
- PatchProcPtr itsAgent;
- Patch* itsPatch;
- };
-
- typedef struct PatchStub PatchStub;
-
- // patch class.
-
- class Patch {
- protected:
- Patch(); // constructor protected to prevent direct use.
-
- public:
- virtual ~Patch(); // destruction is allowed.
-
- void Install(void); // install the patch. delete to remove.
- static void RemoveAll(void); // remove all installed patches.
-
- void Enable(void); // enable the patch.
- void Disable(void); // disable the patch.
- PatchState Switch(PatchState state); // get & set state.
-
- void* operator new(size_t n); // memory allocator.
- void operator delete(void* p); // memory deallocator.
-
- protected:
- virtual PatchProcPtr GetAgent(void); // returns pointer to agent code.
- virtual PatchProcPtr Get(void); // retrieve the old address.
- virtual void Set(PatchProcPtr proc); // set the new address.
-
- protected:
- #ifndef THINK_C
- short itsClassId; // padding for universal glue.
- #endif
- static Patch* theirList; // list of all installed patches.
- Patch* itsNext; // next patch after this one.
-
- PatchProcPtr itsBehavior; // routine to call when patch hit.
- PatchProcPtr itsOld; // old routine to call.
- PatchStub* itsStub; // the universal glue code.
-
- void* itsGlobals; // pointer to globals.
- Boolean itsInstalled; // if patch was ever installed.
- PatchState itsState; // state of patch (enabled/disabled).
- };
-
- class TrapPatch : public Patch {
- public:
- void InitTrapPatch(PatchProcPtr proc, short trap);
-
- protected:
- virtual PatchProcPtr Get(void);
- virtual void Set(PatchProcPtr proc);
-
- protected:
- short itsTrap;
- };
-
- class VectorPatch : public Patch {
- public:
- void InitVectorPatch(PatchProcPtr proc, PatchVectorPtr vector);
-
- protected:
- virtual PatchProcPtr Get(void);
- virtual void Set(PatchProcPtr proc);
-
- private:
- PatchVectorPtr itsVector;
- };
-
- // structure that represents the stack frame when the patch is given control.
-
- struct PatchFrame {
- Patch* patch; // pointer to current patch object.
- void* offset; // magic address to adjust stack for tail patching.
- long rd0; // caller's d0-d2/a0-a1 which might contain
- long rd1; // parameters which patch can change.
- long rd2;
- void* ra0;
- void* ra1;
- void* ra4; // caller's a4 & a5 in case we use a4 globals.
- void* ra5;
- void* link; // link to previous stack frame. 28(sp)
- void* old; // old address that will be returned to.
- void* caller; // caller's address. 36(sp)
- char parameters[1]; // array of parameters (if any)
- };
-
- typedef struct PatchFrame PatchFrame;
-
- struct ExceptionPatchFrame {
- Patch* patch; // pointer to current patch object.
- void* offset; // magic address to adjust stack for tail patching.
- long rd0; // caller's d0-d2/a0-a1 which might contain
- long rd1; // parameters which patch can change.
- long rd2;
- void* ra0;
- void* ra1;
- void* ra4; // caller's a4 & a5 in case we use a4 globals.
- void* ra5;
- void* link; // link to previous stack frame.
- void* old; // old address that will be returned to.
- short status; // value of status register.
- void* caller; // callers's address.
- char parameters[1]; // array of parameters (if any)
- };
-
- typedef struct ExceptionPatchFrame ExceptionPatchFrame;
-
- void CallOS(PatchFrame* frame);
- void VException(ExceptionPatchFrame frame);
- void PatchExceptions(void);
- void RestoreExceptions(void);
-
- #endif
-